<template>
  <div class="single-upload-container">
    <h2>单文件上传示例</h2>

    <!-- 上传区域 -->
    <div class="upload-area" 
         @drop.prevent="handleDrop"
         @dragover.prevent="handleDragOver"
         @dragleave.prevent="handleDragLeave"
         :class="{ 'drag-over': isDragOver }">
      
      <!-- 上传前的展示 -->
      <div v-if="!currentFile" class="upload-placeholder">
        <el-upload
          ref="upload"
          action="#"
          :auto-upload="false"
          :show-file-list="false"
          :on-change="handleFileChange"
          :multiple="false">
          <div class="upload-trigger">
            <i class="el-icon-upload"></i>
            <div class="upload-text">
              <span>点击上传文件或拖拽文件到此处</span>
              <p class="upload-hint">支持格式：jpg、png、pdf、doc、docx、xls、xlsx (不超过50MB)</p>
            </div>
          </div>
        </el-upload>
      </div>

      <!-- 文件信息展示 -->
      <div v-else class="file-info-container">
        <div class="file-info" :class="{ 'upload-success': uploadStatus === 'success', 
                                       'upload-error': uploadStatus === 'error' }">
          <div class="file-preview">
            <i :class="getFileIcon(currentFile.name)"></i>
          </div>
          <div class="file-details">
            <div class="file-name">{{ currentFile.name }}</div>
            <div class="file-size">{{ formatFileSize(currentFile.size) }}</div>
          </div>
          <div class="file-status">
            <template v-if="uploadStatus === 'ready'">
              <el-button type="primary" size="small" @click="uploadFile">
                上传文件
              </el-button>
              <el-button size="small" @click="removeFile">
                移除
              </el-button>
            </template>
            <template v-else-if="uploadStatus === 'uploading'">
              <span class="uploading-text">
                <i class="el-icon-loading"></i>
                正在上传...
              </span>
            </template>
            <template v-else-if="uploadStatus === 'success'">
              <span class="success-text">
                <i class="el-icon-check"></i>
                上传成功
              </span>
              <el-button size="small" @click="removeFile">
                重新上传
              </el-button>
            </template>
            <template v-else-if="uploadStatus === 'error'">
              <span class="error-text">
                <i class="el-icon-close"></i>
                {{ errorMessage }}
              </span>
              <el-button type="warning" size="small" @click="retryUpload">
                重试
              </el-button>
              <el-button size="small" @click="removeFile">
                移除
              </el-button>
            </template>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SingleFileUpload',
  
  data() {
    return {
      currentFile: null,
      uploadStatus: 'ready', // ready, uploading, success, error
      isDragOver: false,
      errorMessage: '',
      acceptedTypes: [
        'image/jpeg', 
        'image/png', 
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      ]
    };
  },

  methods: {
    handleFileChange(file) {
      if (this.validateFile(file)) {
        this.currentFile = file;
        this.uploadStatus = 'ready';
        this.errorMessage = '';
      }
    },

    handleDrop(e) {
      this.isDragOver = false;
      const file = e.dataTransfer.files[0]; // 只取第一个文件
      if (file) {
        const fileObj = {
          raw: file,
          name: file.name,
          size: file.size,
          type: file.type
        };
        
        if (this.validateFile(fileObj)) {
          this.currentFile = fileObj;
          this.uploadStatus = 'ready';
          this.errorMessage = '';
        }
      }
    },

    handleDragOver() {
      this.isDragOver = true;
    },

    handleDragLeave() {
      this.isDragOver = false;
    },

    validateFile(file) {
      const fileType = file.raw ? file.raw.type : file.type;
      
      // 检查文件类型
      if (!this.acceptedTypes.includes(fileType)) {
        const ext = file.name.split('.').pop().toLowerCase();
        const extMap = {
          'jpg': 'image/jpeg',
          'jpeg': 'image/jpeg',
          'png': 'image/png',
          'pdf': 'application/pdf',
          'doc': 'application/msword',
          'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
          'xls': 'application/vnd.ms-excel',
          'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        };
        
        if (!extMap[ext] || !this.acceptedTypes.includes(extMap[ext])) {
          this.$message.error('不支持的文件类型');
          return false;
        }
      }
      
      // 检查文件大小
      const fileSize = file.raw ? file.raw.size : file.size;
      if (fileSize > 50 * 1024 * 1024) {
        this.$message.error('文件大小不能超过50MB');
        return false;
      }

      return true;
    },

    async uploadFile() {
      if (!this.currentFile || this.uploadStatus === 'uploading') return;
      
      this.uploadStatus = 'uploading';
      this.errorMessage = '';

      try {
        // 模拟上传过程
        await new Promise((resolve, reject) => {
          setTimeout(() => {
            if (Math.random() > 0.3) { // 70%概率上传成功
              resolve();
            } else {
              reject(new Error('上传失败，请重试'));
            }
          }, 1500);
        });

        this.uploadStatus = 'success';
        this.$message.success('文件上传成功');
      } catch (error) {
        this.uploadStatus = 'error';
        this.errorMessage = error.message;
        this.$message.error(error.message);
      }
    },

    retryUpload() {
      this.uploadFile();
    },

    removeFile() {
      this.currentFile = null;
      this.uploadStatus = 'ready';
      this.errorMessage = '';
    },

    formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
    },

    getFileIcon(fileName) {
      const ext = fileName.split('.').pop().toLowerCase();
      const icons = {
        jpg: 'el-icon-picture',
        jpeg: 'el-icon-picture',
        png: 'el-icon-picture',
        pdf: 'el-icon-document',
        doc: 'el-icon-document',
        docx: 'el-icon-document',
        xls: 'el-icon-document',
        xlsx: 'el-icon-document'
      };
      return icons[ext] || 'el-icon-document';
    }
  }
};
</script>

<style scoped>
.single-upload-container {
  padding: 20px;
}

h2 {
  color: #2c3e50;
  margin-bottom: 20px;
}

.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 8px;
  padding: 30px;
  background: #fff;
  transition: all 0.3s;
  min-height: 200px;
}

.upload-area.drag-over {
  border-color: #409eff;
  background: #ecf5ff;
}

.upload-placeholder {
  text-align: center;
}

.upload-trigger {
  cursor: pointer;
  padding: 20px;
}

.upload-trigger:hover {
  color: #409eff;
}

.el-icon-upload {
  font-size: 48px;
  color: #909399;
  margin-bottom: 10px;
}

.upload-text {
  color: #606266;
}

.upload-hint {
  font-size: 12px;
  color: #909399;
  margin-top: 10px;
}

.file-info-container {
  padding: 10px;
}

.file-info {
  display: flex;
  align-items: center;
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  transition: all 0.3s;
}

.file-preview {
  font-size: 32px;
  color: #909399;
  margin-right: 15px;
}

.file-details {
  flex: 1;
}

.file-name {
  font-size: 14px;
  color: #303133;
  margin-bottom: 4px;
}

.file-size {
  font-size: 12px;
  color: #909399;
}

.file-status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.uploading-text {
  color: #409EFF;
  display: flex;
  align-items: center;
  gap: 5px;
}

.success-text {
  color: #67c23a;
  display: flex;
  align-items: center;
  gap: 5px;
}

.error-text {
  color: #f56c6c;
  display: flex;
  align-items: center;
  gap: 5px;
}

.upload-success {
  background-color: #f0f9eb;
}

.upload-error {
  background-color: #fef0f0;
}

@media screen and (max-width: 768px) {
  .file-info {
    flex-direction: column;
    text-align: center;
  }

  .file-preview {
    margin-right: 0;
    margin-bottom: 10px;
  }

  .file-status {
    margin-top: 10px;
    justify-content: center;
  }
}
</style> 